﻿using System;
using NetTopologySuite.Utilities;

namespace NetTopologySuite.Index.Quadtree
{
	public class DoubleBits
	{
		public static double PowerOf2(int exp)
		{
			if (exp > 1023 || exp < -1022)
			{
				throw new ArgumentException("Exponent out of bounds");
			}
			return System.BitConverter.Int64BitsToDouble((long)(exp + 1023) << 52);
		}

		public static int GetExponent(double d)
		{
			return new DoubleBits(d).Exponent;
		}

		public static double TruncateToPowerOfTwo(double d)
		{
			DoubleBits doubleBits = new DoubleBits(d);
			doubleBits.ZeroLowerBits(52);
			return doubleBits.Double;
		}

		public static string ToBinaryString(double d)
		{
			return new DoubleBits(d).ToString();
		}

		public static double MaximumCommonMantissa(double d1, double d2)
		{
			if (d1 == 0.0 || d2 == 0.0)
			{
				return 0.0;
			}
			DoubleBits doubleBits = new DoubleBits(d1);
			DoubleBits doubleBits2 = new DoubleBits(d2);
			if (doubleBits.Exponent != doubleBits2.Exponent)
			{
				return 0.0;
			}
			int num = doubleBits.NumCommonMantissaBits(doubleBits2);
			doubleBits.ZeroLowerBits(64 - (12 + num));
			return doubleBits.Double;
		}

		public DoubleBits(double x)
		{
			this.x = x;
			this._xBits = System.BitConverter.DoubleToInt64Bits(x);
		}

		public double Double
		{
			get
			{
				return System.BitConverter.Int64BitsToDouble(this._xBits);
			}
		}

		public int BiasedExponent
		{
			get
			{
				return (int)(this._xBits >> 52) & 2047;
			}
		}

		public int Exponent
		{
			get
			{
				return this.BiasedExponent - 1023;
			}
		}

		public void ZeroLowerBits(int nBits)
		{
			long num = ~((1L << nBits) - 1L);
			this._xBits &= num;
		}

		public int GetBit(int i)
		{
			long num = 1L << i;
			if ((this._xBits & num) == 0L)
			{
				return 0;
			}
			return 1;
		}

		public int NumCommonMantissaBits(DoubleBits db)
		{
			for (int i = 0; i < 52; i++)
			{
				if (this.GetBit(i) != db.GetBit(i))
				{
					return i;
				}
			}
			return 52;
		}

		public override string ToString()
		{
			string str = HexConverter.ConvertAny2Any(this._xBits.ToString(), 10, 2);
			string text = "0000000000000000000000000000000000000000000000000000000000000000" + str;
			string text2 = text.Substring(text.Length - 64);
			return string.Concat(new object[]
			{
				text2.Substring(0, 1),
				"  ",
				text2.Substring(1, 12),
				"(",
				this.Exponent,
				") ",
				text2.Substring(12),
				" [ ",
				this.x,
				" ]"
			});
		}

		public const int ExponentBias = 1023;

		private readonly double x;

		private long _xBits;
	}
}
